/*
 * VCNL4030X01_Application_Library.c
 *
 * Created  : 23 July 2021
 * Modified : 27 July 2021
 * Author   : HWanyusof
 * Version	: 1.1
 */

#include "VCNL4030X01_Application_Library.h"
#include "VCNL4030X01_Prototypes.h"
#include "VCNL4030X01.h"
#include "I2C_Functions.h"

extern int I2C_Bus;

//****************************************************************************************************
//***************************************Application API**********************************************

/*Determine Sensitivity From ALS IT
 *VCNL4030X01_CAL_Sensitivity(Byte ALS_IT)
 *Byte ALS_IT - Input Parameter:
 *
 * VCNL4030X01_ALS_IT_50MS
 * VCNL4030X01_ALS_IT_100MS
 * VCNL4030X01_ALS_IT_200MS
 * VCNL4030X01_ALS_IT_400MS
 * VCNL4030X01_ALS_IT_800MS
 *
 * returns sensitivity in lux/count
 */
float VCNL4030X01_CAL_Sensitivity(Byte ALS_IT)
{
    float Sensitivity;

	if (ALS_IT == VCNL4030X01_ALS_IT_50MS) {Sensitivity = 0.064;}
	if (ALS_IT == VCNL4030X01_ALS_IT_100MS) {Sensitivity = 0.032;}
	if (ALS_IT == VCNL4030X01_ALS_IT_200MS) {Sensitivity = 0.016;}
	if (ALS_IT == VCNL4030X01_ALS_IT_400MS) {Sensitivity = 0.008;}
	if (ALS_IT == VCNL4030X01_ALS_IT_800MS) {Sensitivity = 0.004;}

	return(Sensitivity);
}

/*Calculate the ALS (Lux)
 *VCNL4030X01_CAL_Lux(float Sensitivity, float Count)
 *float Sensitivity - output from VCNL4030X01_CAL_Sensitivity(Byte ALS_IT)
 *float Count - output from VCNL4030X01_GET_ALS_Data()
 *
 * returns lux
 */
float VCNL4030X01_CAL_Lux(float Sensitivity, float Count)
{
    float Lux;
    Lux = Sensitivity*Count;
    return(Lux);
}

/*Get Delay for Measurement
 *VCNL4030X01_GET_Delay()
 *returns delay in ms
 */
int VCNL4030X01_GET_Delay()
{
	int Delay;

	//Delay for ALS
	//Delay = Delay from IT + Circuit (~10ms)
	if (VCNL4030X01_GET_ALS_IT_Bits() == 1) {Delay = 60;}
	if (VCNL4030X01_GET_ALS_IT_Bits() == 2) {Delay = 110;}
	if (VCNL4030X01_GET_ALS_IT_Bits() == 3) {Delay = 210;}
	if (VCNL4030X01_GET_ALS_IT_Bits() == 4) {Delay = 410;}
	if (VCNL4030X01_GET_ALS_IT_Bits() == 5) {Delay = 810;}
	if (VCNL4030X01_GET_ALS_IT_Bits() == 6) {Delay = 810;}
	if (VCNL4030X01_GET_ALS_IT_Bits() == 7) {Delay = 810;}
	if (VCNL4030X01_GET_ALS_IT_Bits() == 8) {Delay = 810;}

	return Delay;
}

/*Get ALS_IT
 *VCNL4030X01_GET_ALS_IT()
 *returns ALS_IT
 */
Byte VCNL4030X01_GET_ALS_IT()
{

	//Delay = Delay from IT + Circuit (~10ms)
	if (VCNL4030X01_GET_ALS_IT_Bits() == 1) {return VCNL4030X01_ALS_IT_50MS;}
	if (VCNL4030X01_GET_ALS_IT_Bits() == 2) {return VCNL4030X01_ALS_IT_100MS;}
	if (VCNL4030X01_GET_ALS_IT_Bits() == 3) {return VCNL4030X01_ALS_IT_200MS;}
	if (VCNL4030X01_GET_ALS_IT_Bits() == 4) {return VCNL4030X01_ALS_IT_400MS;}
	if (VCNL4030X01_GET_ALS_IT_Bits() == 5) {return VCNL4030X01_ALS_IT_800MS;}
	if (VCNL4030X01_GET_ALS_IT_Bits() == 6) {return VCNL4030X01_ALS_IT_800MS;}
	if (VCNL4030X01_GET_ALS_IT_Bits() == 7) {return VCNL4030X01_ALS_IT_800MS;}
	if (VCNL4030X01_GET_ALS_IT_Bits() == 8) {return VCNL4030X01_ALS_IT_800MS;}
	else
	return 0;
}

/*Get Proximity Mode
 *returns the PS mode status of the sensor as follows:
 *
 * 0 - PS Shutdown Mode
 * 1 - Auto/Self-Timed Mode
 * 2 - Active Force Mode/Continuous Forced Mode
 * 4 - Low Power Mode
 *
 */
int VCNL4030X01_GET_PS_Mode()
{
	int Mode;

	//Read the PS_SD bit: Mode = 0 - PS Shutdown
	if (VCNL4030X01_GET_PS_SD_Bit() == 0b1) Mode = 0;

	//Read the PS_AF bit and PS_SD: Mode = 1 - Auto/Self-Timed Mode
	if ((VCNL4030X01_GET_PS_AF_Bit() == 0b0) && (VCNL4030X01_GET_PS_SD_Bit() == 0b0)) Mode = 1;

	//Read the PS_AF bit: Mode = 2 - AF Mode
	if (VCNL4030X01_GET_PS_AF_Bit() == 0b1) Mode = 2;

	//Read the LED_I_LOW bit: Mode = 4 - Low Power Mode
	if (VCNL4030X01_GET_LED_I_LOW_Bit() == 0b1) Mode = 4;

	return Mode;
}

/*Get ALS Mode
 *returns the ALS mode status of the sensor as follows:
 *
 * 0 - ALS Shutdown Mode
 * 1 - ALS Mode
 * 2 - White Channel Mode
 *
 */
int VCNL4030X01_GET_ALS_Mode()
{
	int Mode;

	//Read the ALS_SD bit: Mode = 0 - ALS Shutdown
	if (VCNL4030X01_GET_ALS_SD_Bit() == 0b1) Mode = 0;

	//Read the WHITE_SD and ALS_SD bit: Mode = 1 - ALS Mode
	if ((VCNL4030X01_GET_WHITE_SD_Bit() == 0b1) && (VCNL4030X01_GET_ALS_SD_Bit() == 0b0)) Mode = 1;

	//Read the WHITE_SD bit: Mode = 2 - White Mode
	if (VCNL4030X01_GET_WHITE_SD_Bit() == 0b0) Mode = 2;

	return Mode;
}

//Reset the Sensor to the default value
void Reset_Sensor()
{
	struct TransferData VCNL4030X01_Data;
	VCNL4030X01_Data.Slave_Address = VCNL4030X01_SlaveAddress;
	VCNL4030X01_Data.RegisterAddress = VCNL4030X01_ALS_CONF_1;
	VCNL4030X01_Data.Select_I2C_Bus = I2C_Bus;
	VCNL4030X01_Data.WData[0] = 0x01;
	VCNL4030X01_Data.WData[1] = 0x01;
	WriteI2C_Bus(&VCNL4030X01_Data);

	VCNL4030X01_Data.Slave_Address = VCNL4030X01_SlaveAddress;
	VCNL4030X01_Data.RegisterAddress = VCNL4030X01_ALS_THDL;
	VCNL4030X01_Data.Select_I2C_Bus = I2C_Bus;
	VCNL4030X01_Data.WData[0] = 0x00;
	VCNL4030X01_Data.WData[1] = 0x00;
	WriteI2C_Bus(&VCNL4030X01_Data);

	VCNL4030X01_Data.Slave_Address = VCNL4030X01_SlaveAddress;
	VCNL4030X01_Data.RegisterAddress = VCNL4030X01_ALS_THDH;
	VCNL4030X01_Data.Select_I2C_Bus = I2C_Bus;
	VCNL4030X01_Data.WData[0] = 0x00;
	VCNL4030X01_Data.WData[1] = 0x00;
	WriteI2C_Bus(&VCNL4030X01_Data);

	VCNL4030X01_Data.Slave_Address = VCNL4030X01_SlaveAddress;
	VCNL4030X01_Data.RegisterAddress = VCNL4030X01_PS_CONF_1;
	VCNL4030X01_Data.Select_I2C_Bus = I2C_Bus;
	VCNL4030X01_Data.WData[0] = 0x01;
	VCNL4030X01_Data.WData[1] = 0x00;
	WriteI2C_Bus(&VCNL4030X01_Data);

	VCNL4030X01_Data.Slave_Address = VCNL4030X01_SlaveAddress;
	VCNL4030X01_Data.RegisterAddress = VCNL4030X01_PS_CONF_3;
	VCNL4030X01_Data.Select_I2C_Bus = I2C_Bus;
	VCNL4030X01_Data.WData[0] = 0x00;
	VCNL4030X01_Data.WData[1] = 0x00;
	WriteI2C_Bus(&VCNL4030X01_Data);

    VCNL4030X01_Data.Slave_Address = VCNL4030X01_SlaveAddress;
	VCNL4030X01_Data.RegisterAddress = VCNL4030X01_PS_CANC;
	VCNL4030X01_Data.Select_I2C_Bus = I2C_Bus;
	VCNL4030X01_Data.WData[0] = 0x00;
	VCNL4030X01_Data.WData[1] = 0x00;
	WriteI2C_Bus(&VCNL4030X01_Data);

	VCNL4030X01_Data.Slave_Address = VCNL4030X01_SlaveAddress;
	VCNL4030X01_Data.RegisterAddress = VCNL4030X01_PS_THDL;
	VCNL4030X01_Data.Select_I2C_Bus = I2C_Bus;
	VCNL4030X01_Data.WData[0] = 0x00;
	VCNL4030X01_Data.WData[1] = 0x00;
	WriteI2C_Bus(&VCNL4030X01_Data);

	VCNL4030X01_Data.Slave_Address = VCNL4030X01_SlaveAddress;
	VCNL4030X01_Data.RegisterAddress = VCNL4030X01_PS_THDH;
	VCNL4030X01_Data.Select_I2C_Bus = I2C_Bus;
	VCNL4030X01_Data.WData[0] = 0x00;
	VCNL4030X01_Data.WData[1] = 0x00;
	WriteI2C_Bus(&VCNL4030X01_Data);

	VCNL4030X01_Data.Slave_Address = VCNL4030X01_SlaveAddress;
	VCNL4030X01_Data.RegisterAddress = VCNL4030X01_INT_FLAG;
	VCNL4030X01_Data.Select_I2C_Bus = I2C_Bus;
	VCNL4030X01_Data.WData[0] = 0x00;
	VCNL4030X01_Data.WData[1] = 0x00;
	WriteI2C_Bus(&VCNL4030X01_Data);
}

/*Print all of the Register Value for both proximity and ambient light sensing functions
 *Print_All()
 */
void Print_All()
{
	Word value;
	int Delay;
	float Sensitivity;
	float Lux;
	Byte ALS_IT = VCNL4030X01_GET_ALS_IT();

	#define TRANSMIT_BUFFER_SIZE  128
	char   TransmitBuffer[TRANSMIT_BUFFER_SIZE];
	char   TransmitBuffer2[TRANSMIT_BUFFER_SIZE];

	sprintf(TransmitBuffer2,"*************************************************** \r\n");
	CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
	HAL_Delay(50);

	//Print ALS Mode
	switch(VCNL4030X01_GET_ALS_Mode())
	{
		case 0 :	sprintf(TransmitBuffer2,">>>>>>>Mode : ALS Off/Shutdown \r\n");
					CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
					HAL_Delay(50);
					break;
		case 1 :	sprintf(TransmitBuffer2,">>>>>>>Mode : ALS Mode \r\n");
					CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
					HAL_Delay(50);
					break;
		case 2 :	sprintf(TransmitBuffer2,">>>>>>>Mode : White Mode \r\n");
					CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
					HAL_Delay(50);
					break;
	}

	sprintf(TransmitBuffer2,">>>>>>>>>>>>>>>>>>>>>>>ALS<<<<<<<<<<<<<<<<<<<<<<<<< \r\n");
	CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
	HAL_Delay(50);

	//Print the Reg 0x00 (ALS_CONF1 and ALS_CONF2)
	value = VCNL4030X01_READ_Reg(VCNL4030X01_ALS_CONF_1);
	sprintf(TransmitBuffer,">>>>>>>Reg 0x00 (ALS_CONF) Val : 0x%x \r\n",value);
	CDC_Transmit_FS(TransmitBuffer,strlen(TransmitBuffer));
	HAL_Delay(50);

	//Print the Reg 0x01 (ALS_THDH)
	value = VCNL4030X01_READ_Reg(VCNL4030X01_ALS_THDH);
	sprintf(TransmitBuffer,">>>>>>>Reg 0x01 (ALS_THDH) Val : %d Counts\r\n",value);
	CDC_Transmit_FS(TransmitBuffer,strlen(TransmitBuffer));
	HAL_Delay(50);

	//Print the Reg 0x02 (ALS_THDL)
	value = VCNL4030X01_READ_Reg(VCNL4030X01_ALS_THDL);
	sprintf(TransmitBuffer,">>>>>>>Reg 0x02 (ALS_THDL) Val : %d Counts\r\n",value);
	CDC_Transmit_FS(TransmitBuffer,strlen(TransmitBuffer));
	HAL_Delay(50);

	//Get Delay for ALS Measurement
	Delay = VCNL4030X01_GET_Delay();

	//Delay of IT ms + other Circuit Delay (~10ms)
	HAL_Delay(Delay);

	//Print ALS Data
	if(VCNL4030X01_GET_ALS_Mode() == 1)
	{
		//Find Sensitivity
		Sensitivity = VCNL4030X01_CAL_Sensitivity(ALS_IT);

		//Print the Sensitivity
		ftoa(Sensitivity,TransmitBuffer, 6);
		sprintf(TransmitBuffer2,">>>>>>>Sensitivity : %s lx/Count<<<<<<<<\r\n",TransmitBuffer);
		CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
		HAL_Delay(50);

		//Print the ALS Data in DEC
		value = VCNL4030X01_GET_ALS_Data();
		sprintf(TransmitBuffer,">>>>>>>ALS Data : %d Counts<<<<<<<<\r\n",value);
		CDC_Transmit_FS(TransmitBuffer,strlen(TransmitBuffer));
		HAL_Delay(50);

		//Calculate Lux
		Lux = VCNL4030X01_CAL_Lux(Sensitivity, value);

		//Print the ALS Lux in DEC
		ftoa(Lux,TransmitBuffer, 5);
		sprintf(TransmitBuffer2,">>>>>>>ALS Lux : %s lx<<<<<<<<\r\n",TransmitBuffer);
		CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
		HAL_Delay(50);
	}

	//Print White Data
	if(VCNL4030X01_GET_ALS_Mode() == 2)
	{
		//Print the White Data in DEC
		value = VCNL4030X01_GET_White_Data();
		sprintf(TransmitBuffer,">>>>>>>White Data : %d Counts<<<<<<<<\r\n",value);
		CDC_Transmit_FS(TransmitBuffer,strlen(TransmitBuffer));
		HAL_Delay(50);
	}

	//Print the Interrupt Flag
	//Only print here when PS is off/shutdown and ALS/White channel is on
	if((VCNL4030X01_GET_PS_Mode() == 0) && (VCNL4030X01_GET_ALS_Mode() != 0))
	{
		sprintf(TransmitBuffer2,"*************************************************** \r\n");
		CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
		HAL_Delay(50);

		value = VCNL4030X01_GET_ALS_Interrupt();
		sprintf(TransmitBuffer,">>>>>>>Interrupt Flag : 0x%x<<<<<<<< \r\n",value);
		CDC_Transmit_FS(TransmitBuffer,strlen(TransmitBuffer));
		HAL_Delay(50);
	}

	sprintf(TransmitBuffer2,"*************************************************** \r\n");
	CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
	HAL_Delay(50);

	//Print PS Mode
	switch(VCNL4030X01_GET_PS_Mode())
	{
		case 0 :	sprintf(TransmitBuffer2,">>>>>>>Mode : PS Off/Shutdown \r\n");
					CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
					HAL_Delay(50);
					break;
		case 1 :	sprintf(TransmitBuffer2,">>>>>>>Mode : Auto/Self-Timed Mode \r\n");
					CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
					HAL_Delay(50);
					break;
		case 2 :	sprintf(TransmitBuffer2,">>>>>>>Mode : AF/Continuous Forced Mode \r\n");
					CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
					HAL_Delay(50);
					break;
		case 4 :	sprintf(TransmitBuffer2,">>>>>>>Mode : Low Power Mode \r\n");
					CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
					HAL_Delay(50);
					break;
	}

	sprintf(TransmitBuffer2,">>>>>>>>>>>>>>>>>>>>>>>>PS<<<<<<<<<<<<<<<<<<<<<<<<< \r\n");
	CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
	HAL_Delay(50);

	//Print the Reg 0x03 (PS_CONF1 and PS_CONF2)
	value = VCNL4030X01_READ_Reg(VCNL4030X01_PS_CONF_1);
	sprintf(TransmitBuffer,">>>>>>>Reg 0x03 (PS_CONF1) Val : 0x%x \r\n",value);
	CDC_Transmit_FS(TransmitBuffer,strlen(TransmitBuffer));
	HAL_Delay(50);

	//Print the Reg 0x04 (PS_CONF3 and PS_MS)
	value = VCNL4030X01_READ_Reg(VCNL4030X01_PS_CONF_3);
	sprintf(TransmitBuffer,">>>>>>>Reg 0x04 (PS_CONF3) Val : 0x%x \r\n",value);
	CDC_Transmit_FS(TransmitBuffer,strlen(TransmitBuffer));
	HAL_Delay(50);

	//Print the Reg 0x05 (PS_CANC)
	value = VCNL4030X01_READ_Reg(VCNL4030X01_PS_CANC);
	sprintf(TransmitBuffer,">>>>>>>Reg 0x05 (PS_CANC) Val : %d Counts \r\n",value);
	CDC_Transmit_FS(TransmitBuffer,strlen(TransmitBuffer));
	HAL_Delay(50);

	//Print the Reg 0x06 (PS_THDL)
	value = VCNL4030X01_READ_Reg(VCNL4030X01_PS_THDL);
	sprintf(TransmitBuffer,">>>>>>>Reg 0x06 (PS_THDL) Val : %d Counts \r\n",value);
	CDC_Transmit_FS(TransmitBuffer,strlen(TransmitBuffer));
	HAL_Delay(50);

	//Print the Reg 0x07 (PS_THDH)
	value = VCNL4030X01_READ_Reg(VCNL4030X01_PS_THDH);
	sprintf(TransmitBuffer,">>>>>>>Reg 0x07 (PS_THDH) Val : %d Counts \r\n",value);
	CDC_Transmit_FS(TransmitBuffer,strlen(TransmitBuffer));
	HAL_Delay(50);

	//Print Proximity Data (Only For Auto Mode, AF and Low Power Mode)
	if((VCNL4030X01_GET_PS_Mode() > 0) && (VCNL4030X01_GET_PS_Mode() < 5))
	{
		//Set Trigger for AF Mode + Associated delay due to IT
		if(VCNL4030X01_GET_PS_Mode() == 2)
		{
			//Set trigger to start a measurement
			VCNL4030X01_SET_PS_TRIG(VCNL4030X01_PS_TRIG_EN);

			//Delay of PS Measurement + other Circuit Delay
			HAL_Delay(50);
		}

		//Delay for Auto and Low Power Mode + Associated delay due to IT
		if((VCNL4030X01_GET_PS_Mode() == 1) || (VCNL4030X01_GET_PS_Mode() == 4))
		{
			//Delay of PS Measurement + other Circuit Delay
			HAL_Delay(50);
		}

		//Print the Proximity Data
		value = VCNL4030X01_READ_Reg(VCNL4030X01_PS_DATA);
		sprintf(TransmitBuffer,">>>>>>>Proximity Data : %d Counts<<<<<<<< \r\n",value);
		CDC_Transmit_FS(TransmitBuffer,strlen(TransmitBuffer));
		HAL_Delay(50);
	}

	//Print the Interrupt Flag
	if(((VCNL4030X01_GET_ALS_Mode() != 0) && (VCNL4030X01_GET_PS_Mode() != 0)) || ((VCNL4030X01_GET_ALS_Mode() == 0) && (VCNL4030X01_GET_PS_Mode() == 0)) || ((VCNL4030X01_GET_ALS_Mode() == 0) && (VCNL4030X01_GET_PS_Mode() != 0)))
	{
		sprintf(TransmitBuffer2,"*************************************************** \r\n");
		CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
		HAL_Delay(50);

		//Print the Interrupt Flag
		value = VCNL4030X01_GET_PS_Interrupt();
		sprintf(TransmitBuffer,">>>>>>>Interrupt Flag : 0x%x<<<<<<<< \r\n",value);
		CDC_Transmit_FS(TransmitBuffer,strlen(TransmitBuffer));
		HAL_Delay(50);
	}

	sprintf(TransmitBuffer2,"*************************************************** \r\n");
	CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
	HAL_Delay(50);

	sprintf(TransmitBuffer2," \r\n");
	CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
	HAL_Delay(50);

	sprintf(TransmitBuffer2," \r\n");
	CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));

	HAL_Delay(2000);
}

//Print the output of the sensor
void Print_Data_Only()
{
	Word value;
	int Delay;
	float Sensitivity;
	float Lux;
	Byte ALS_IT = VCNL4030X01_GET_ALS_IT();

	#define TRANSMIT_BUFFER_SIZE  128
	char   TransmitBuffer[TRANSMIT_BUFFER_SIZE];
	char   TransmitBuffer2[TRANSMIT_BUFFER_SIZE];

	sprintf(TransmitBuffer2,"*************************************************** \r\n");
	CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
	HAL_Delay(50);

	//Print ALS Mode
	switch(VCNL4030X01_GET_ALS_Mode())
	{
		case 0 :	sprintf(TransmitBuffer2,">>>>>>>Mode : ALS Off/Shutdown \r\n");
					CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
					HAL_Delay(50);
					break;
		case 1 :	sprintf(TransmitBuffer2,">>>>>>>Mode : ALS Mode \r\n");
					CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
					HAL_Delay(50);
					break;
		case 2 :	sprintf(TransmitBuffer2,">>>>>>>Mode : White Mode \r\n");
					CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
					HAL_Delay(50);
					break;
	}

	sprintf(TransmitBuffer2,">>>>>>>>>>>>>>>>>>>>>>>ALS<<<<<<<<<<<<<<<<<<<<<<<<< \r\n");
	CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
	HAL_Delay(50);

	//Get Delay for ALS Measurement
	Delay = VCNL4030X01_GET_Delay();

	//Delay of IT ms + other Circuit Delay (~10ms)
	HAL_Delay(Delay);

	//Print ALS Data
	if(VCNL4030X01_GET_ALS_Mode() == 1)
	{
		//Find Sensitivity
		Sensitivity = VCNL4030X01_CAL_Sensitivity(ALS_IT);

		//Print the Sensitivity
		ftoa(Sensitivity,TransmitBuffer, 6);
		sprintf(TransmitBuffer2,">>>>>>>Sensitivity : %s lx/Count<<<<<<<<\r\n",TransmitBuffer);
		CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
		HAL_Delay(50);

		//Print the ALS Data in DEC
		value = VCNL4030X01_GET_ALS_Data();
		sprintf(TransmitBuffer,">>>>>>>ALS Data : %d Counts<<<<<<<<\r\n",value);
		CDC_Transmit_FS(TransmitBuffer,strlen(TransmitBuffer));
		HAL_Delay(50);

		//Calculate Lux
		Lux = VCNL4030X01_CAL_Lux(Sensitivity, value);

		//Print the ALS Lux in DEC
		ftoa(Lux,TransmitBuffer, 5);
		sprintf(TransmitBuffer2,">>>>>>>ALS Lux : %s lx<<<<<<<<\r\n",TransmitBuffer);
		CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
		HAL_Delay(50);
	}

	//Print White Data
	if(VCNL4030X01_GET_ALS_Mode() == 2)
	{
		//Print the White Data in DEC
		value = VCNL4030X01_GET_White_Data();
		sprintf(TransmitBuffer,">>>>>>>White Data : %d Counts<<<<<<<<\r\n",value);
		CDC_Transmit_FS(TransmitBuffer,strlen(TransmitBuffer));
		HAL_Delay(50);
	}

	//Print the Interrupt Flag
	//Only print here when PS is off/shutdown and ALS/White channel is on
	if((VCNL4030X01_GET_PS_Mode() == 0) && (VCNL4030X01_GET_ALS_Mode() != 0))
	{
		sprintf(TransmitBuffer2,"*************************************************** \r\n");
		CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
		HAL_Delay(50);

		value = VCNL4030X01_GET_ALS_Interrupt();
		sprintf(TransmitBuffer,">>>>>>>Interrupt Flag : 0x%x<<<<<<<< \r\n",value);
		CDC_Transmit_FS(TransmitBuffer,strlen(TransmitBuffer));
		HAL_Delay(50);
	}

	sprintf(TransmitBuffer2,"*************************************************** \r\n");
	CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
	HAL_Delay(50);

	//Print PS Mode
	switch(VCNL4030X01_GET_PS_Mode())
	{
		case 0 :	sprintf(TransmitBuffer2,">>>>>>>Mode : PS Off/Shutdown \r\n");
					CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
					HAL_Delay(50);
					break;
		case 1 :	sprintf(TransmitBuffer2,">>>>>>>Mode : Auto/Self-Timed Mode \r\n");
					CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
					HAL_Delay(50);
					break;
		case 2 :	sprintf(TransmitBuffer2,">>>>>>>Mode : AF/Continuous Forced Mode \r\n");
					CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
					HAL_Delay(50);
					break;
		case 4 :	sprintf(TransmitBuffer2,">>>>>>>Mode : Low Power Mode \r\n");
					CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
					HAL_Delay(50);
					break;
	}

	sprintf(TransmitBuffer2,">>>>>>>>>>>>>>>>>>>>>>>>PS<<<<<<<<<<<<<<<<<<<<<<<<< \r\n");
	CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
	HAL_Delay(50);

	//Print Proximity Data (Only For Auto Mode, AF and Low Power Mode)
	if((VCNL4030X01_GET_PS_Mode() > 0) && (VCNL4030X01_GET_PS_Mode() < 5))
	{
		//Set Trigger for AF Mode + Associated delay due to IT
		if(VCNL4030X01_GET_PS_Mode() == 2)
		{
			//Set trigger to start a measurement
			VCNL4030X01_SET_PS_TRIG(VCNL4030X01_PS_TRIG_EN);

			//Delay of PS Measurement + other Circuit Delay
			HAL_Delay(50);
		}

		//Delay for Auto and Low Power Mode + Associated delay due to IT
		if((VCNL4030X01_GET_PS_Mode() == 1) || (VCNL4030X01_GET_PS_Mode() == 4))
		{
			//Delay of PS Measurement + other Circuit Delay
			HAL_Delay(50);
		}

		//Print the Proximity Data
		value = VCNL4030X01_READ_Reg(VCNL4030X01_PS_DATA);
		sprintf(TransmitBuffer,">>>>>>>Proximity Data : %d Counts<<<<<<<< \r\n",value);
		CDC_Transmit_FS(TransmitBuffer,strlen(TransmitBuffer));
		HAL_Delay(50);
	}

	//Print the Interrupt Flag
	if(((VCNL4030X01_GET_ALS_Mode() != 0) && (VCNL4030X01_GET_PS_Mode() != 0)) || ((VCNL4030X01_GET_ALS_Mode() == 0) && (VCNL4030X01_GET_PS_Mode() == 0)) || ((VCNL4030X01_GET_ALS_Mode() == 0) && (VCNL4030X01_GET_PS_Mode() != 0)))
	{
		sprintf(TransmitBuffer2,"*************************************************** \r\n");
		CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
		HAL_Delay(50);

		//Print the Interrupt Flag
		value = VCNL4030X01_GET_PS_Interrupt();
		sprintf(TransmitBuffer,">>>>>>>Interrupt Flag : 0x%x<<<<<<<< \r\n",value);
		CDC_Transmit_FS(TransmitBuffer,strlen(TransmitBuffer));
		HAL_Delay(50);
	}

	sprintf(TransmitBuffer2,"*************************************************** \r\n");
	CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
	HAL_Delay(50);

	sprintf(TransmitBuffer2," \r\n");
	CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
	HAL_Delay(50);

	sprintf(TransmitBuffer2," \r\n");
	CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));

	HAL_Delay(2000);
}

/*Print the variable in DEC for debugging
 *Print_Variable_DEC(Word Var)
 *Word Var - Input Parameter:
 *
 * Value between 0d0 and 0d65535
 */
void Print_Variable_DEC(Word Var)
{

	#define TRANSMIT_BUFFER_SIZE  128
	char   TransmitBuffer[TRANSMIT_BUFFER_SIZE];
	char   TransmitBuffer2[TRANSMIT_BUFFER_SIZE];

	sprintf(TransmitBuffer2,"*************************************************** \r\n");
	CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
	HAL_Delay(50);

	sprintf(TransmitBuffer,">>>>>>>Variable : 0d%d  \r\n",Var);
	CDC_Transmit_FS(TransmitBuffer,strlen(TransmitBuffer));
	HAL_Delay(50);

	sprintf(TransmitBuffer2,"*************************************************** \r\n");
	CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));

	HAL_Delay(2000);

}

/*Print the variable in HEX for debugging
 *Print_Variable_HEX(Word Var)
 *Word Var - Input Parameter:
 *
 * Value between 0d0 and 0d65535
 */
void Print_Variable_HEX(Word Var)
{

	#define TRANSMIT_BUFFER_SIZE  128
	char   TransmitBuffer[TRANSMIT_BUFFER_SIZE];
	char   TransmitBuffer2[TRANSMIT_BUFFER_SIZE];

	sprintf(TransmitBuffer2,"*************************************************** \r\n");
	CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));
	HAL_Delay(50);

	sprintf(TransmitBuffer,">>>>>>>Variable : 0x%x  \r\n",Var);
	CDC_Transmit_FS(TransmitBuffer,strlen(TransmitBuffer));
	HAL_Delay(50);

	sprintf(TransmitBuffer2,"*************************************************** \r\n");
	CDC_Transmit_FS(TransmitBuffer2,strlen(TransmitBuffer2));

	HAL_Delay(2000);

}

//Reverses a string 'str' of length 'len'
void reverse(char* str, int len)
{
    int i = 0, j = len - 1, temp;
    while (i < j) {
        temp = str[i];
        str[i] = str[j];
        str[j] = temp;
        i++;
        j--;
    }
}

//Converts a given integer x to string str[].
//d is the number of digits required in the output.
//If d is more than the number of digits in x,
//then 0s are added at the beginning.
int intToStr(int x, char str[], int d)
{
    int i = 0;

    while (x)
	{
		//Store and convert int to char (Valid for single digit)
        str[i++] = (x % 10) + '0';
        x = x / 10;
    }

    //If number of digits required is more, then
    //add 0s at the beginning
    while (i < d) str[i++] = '0';

	//Reverse the string characters in the array str
    reverse(str, i);

	//Place the null character at the end of the array
    str[i] = '\0';

	//Return the position i
    return i;
}

//Converts a floating-point/double number to a string.
void ftoa(float n, char* res, int afterpoint)
{
    //Extract integer part
    int ipart = (int)n;

    //Extract decimal part
    float fpart = n - (float)ipart;

    //Convert integer part to string and the function returns the position after the interger
    int i = intToStr(ipart, res, 0);

    //Check for display option after point
    if (afterpoint != 0)
	{
		//Add dot after the integer part
        res[i] = '.';

        //Multiply decimal part by 10^decimal point
        fpart = fpart* pow(10, afterpoint);

		//Convert decimal part to string
        intToStr((int)fpart, res + i + 1, afterpoint);
    }
}
